package com.irdstudio.efp.esb.api.rest.sed.rate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.util.TraceUtil;
import com.irdstudio.efp.console.service.facade.sed.STaxOrgMapService;
import com.irdstudio.efp.console.service.vo.sed.STaxOrgMapVO;
import com.irdstudio.efp.cus.service.facade.CusWhiteListEService;
import com.irdstudio.efp.cus.service.facade.OrgWhiteListEService;
import com.irdstudio.efp.cus.service.vo.CusWhiteListEVO;
import com.irdstudio.efp.cus.service.vo.OrgWhiteListEVO;
import com.irdstudio.efp.esb.api.bean.sed.rate.ReqSedQueryRateBean;
import com.irdstudio.efp.esb.api.bean.sed.rate.RespSedQueryRateBean;
import com.irdstudio.efp.esb.api.common.EsbRespServiceBeanCreator;
import com.irdstudio.efp.esb.common.constant.EsbBizEnums;
import com.irdstudio.efp.esb.common.constant.EsbSysHeadEnums;
import com.irdstudio.efp.esb.common.server.req.EsbReqServiceBean;
import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.efp.esb.service.bo.req.sed.hj.ReqSedQueryExecRateBean;
import com.irdstudio.efp.esb.service.bo.resp.sed.hj.RespSedQueryExecRateBean;
import com.irdstudio.efp.esb.service.facade.sed.hj.SedQueryExecRateService;
import com.irdstudio.efp.limit.service.facade.LmtPrdContService;
import com.irdstudio.efp.limit.service.vo.LmtPrdContVO;
import com.irdstudio.efp.rule.service.facade.TaxIncomeTaxInfoService;
import com.irdstudio.efp.rule.service.facade.TaxWithholdRemitCorpService;
import com.irdstudio.efp.rule.service.vo.TaxIncomeTaxInfoVO;
import com.irdstudio.efp.rule.service.vo.TaxWithholdRemitCorpVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Objects;

/**
 * 执行利率查询
 * 
 * @author weijj
 * @since 2019年4月22日 下午16:57:08
 * @version 1.0
 */
@RestController
@RequestMapping("/esb")
public class NlsQueryRateSedController {
	private static Logger logger = LoggerFactory.getLogger(NlsQueryRateSedController.class);

	/**
	 * 获取ESB请求对象，校验 ESB请求系统头和请求应用头对象
	 * 
	 * @param request
	 *            请求对象集合
	 * @return
	 * @author weijj
	 * @since 2019年4月22日 下午16:57:08
	 * @version 1.0
	 */
	@ModelAttribute("esbReqServiceBean")
	public EsbReqServiceBean getReqEsbHeadBean(HttpServletRequest request) {
		logger.info("校验 ESB请求系统头和请求应用头对象!");
		EsbReqServiceBean esbReqServiceBean = (EsbReqServiceBean) request.getAttribute("esbReqServiceBean");
		return esbReqServiceBean;
	}

	/**
	 * 获取ESB请求对象，校验 ESB请求体对象
	 * 
	 * @param request
	 *            请求对象集合
	 * @return
	 * @author weijj
	 * @since 2019年4月22日 下午16:57:08
	 * @version 1.0
	 */
	@ModelAttribute("reqSedQueryRateBean")
	public ReqSedQueryRateBean getReqEsbBodyBean(HttpServletRequest request) {
		logger.info("校验 ESB请求体对象！");
		String esbReqBody = (String) request.getAttribute("esbReqBody");
		return JSONObject.parseObject(esbReqBody, ReqSedQueryRateBean.class);
	}

	/**
	 * 1.通过切面校验进件申请参数是否正确，如不正确则返回错误信息<br>
	 * 2.调用对应的中台服务<br>
	 * 3.执行利率查询<br>
	 * 
	 * @param esbReqServiceBean
	 *            ESB请求对象
	 * @param br1
	 * @param reqSedQueryRateBean
	 *            ESB请求体的对象
	 * @param br2
	 * @param exception
	 *            切面的异常信息
	 * @return
	 * @throws Exception
	 * @author weijj
	 * @since 2019年4月22日 下午16:57:08
	 * @version 1.0
	 */

	@PostMapping("/SERVICE_30230003_07")
	public EsbRespServiceBean doRecv(
            @Validated @ModelAttribute("esbReqServiceBean") EsbReqServiceBean esbReqServiceBean, BindingResult br1,
            @Validated @ModelAttribute("reqSedQueryRateBean") ReqSedQueryRateBean reqSedQueryRateBean,
            BindingResult br2, Exception exception) throws Exception {
		// 授信申请流水号
		String lmtApplySeq = reqSedQueryRateBean.getCrdtAppFlowNo();
		//授信协议号
		String crdAgrmNo = reqSedQueryRateBean.getCrdAgrmNo();
		// 全局流水号
		String glblSrlNo = esbReqServiceBean.getSysHead().getGlblSrlNo();
		TraceUtil.setTraceId(glblSrlNo);
		logger.info("执行利率查询开始----------授信申请流水号：" + lmtApplySeq + "------------全局流水号" + glblSrlNo);
		BigDecimal fltIntRt = null;
		BigDecimal intRate = null;
		try {
			// 1.通过切面校验进件申请参数是否正确，如不正确则返回错误信息
			if (Objects.nonNull(exception)) {
				throw exception;
			}
			checkTrm(reqSedQueryRateBean.getLoanTrm());
			// 单位转换
			final int oneHundred_100 = 100;
			// 2.获取业务逻辑字段
			LmtPrdContVO lmtPrdContVO = new LmtPrdContVO();
			CusWhiteListEVO cusWhiteListEVO = new CusWhiteListEVO();
			STaxOrgMapVO sTaxOrgMapVO = new STaxOrgMapVO();
			OrgWhiteListEVO orgWhiteListEVO = new OrgWhiteListEVO();
			TaxWithholdRemitCorpVO taxWithholdRemitCorpVO = new TaxWithholdRemitCorpVO();
			TaxIncomeTaxInfoVO taxIncomeTaxInfoVO = new TaxIncomeTaxInfoVO();
			ReqSedQueryExecRateBean reqSedQueryExecRateBean = new ReqSedQueryExecRateBean();
			String svcFld = "MBSD_BP_LM";  //服务领域
			String svcTp = "1400"; //服务类型
			String serviceCd = "0110";//互金服务编码
			String term = reqSedQueryRateBean.getLoanTrm(); // 期限

			//期限类型
			String termType = changeTermType(reqSedQueryRateBean.getLoanTrmType());
			String certType = reqSedQueryRateBean.getCertTp(); // 证件类型
			String certNo = reqSedQueryRateBean.getCertNo();// 证件号码
			reqSedQueryExecRateBean.setLoanTrm(term);
			reqSedQueryExecRateBean.setLoanTrmType(termType);
			reqSedQueryExecRateBean.setSvcFld(svcFld);
			reqSedQueryExecRateBean.setSvcTp(svcTp);
			reqSedQueryExecRateBean.setServiceCd(serviceCd);
			//根据授信申请流水号
			lmtPrdContVO = lmtPrdContService.qryLmtPrdContByLmtApplySeq(lmtApplySeq);
			if (Objects.isNull(lmtPrdContVO)|| StringUtils.isEmpty(lmtPrdContVO.getCertCode())
					|| StringUtils.isEmpty(lmtPrdContVO.getCertType())) {
				throw new BizException(EsbRetCodeStandard.KHXXJYBTG.getValue(), "查找不到证件类型和证件号码");
			}

			if (!crdAgrmNo.equals(lmtPrdContVO.getLmtContNo())) {
				throw new BizException(EsbRetCodeStandard.KHXXJYBTG.getValue(), "非客户授信协议号");
			}

			// 证件类型
			String certType1 = lmtPrdContVO.getCertType();
			// 证件号码
			String certNo1 = lmtPrdContVO.getCertCode();


			if (certType.equals(certType1) && certNo.equals(certNo1)) {
				cusWhiteListEVO.setCertType(certType1);
				cusWhiteListEVO.setCertCode(certNo1);
				CusWhiteListEVO queryCusWhiteListEVO = cusWhiteListEService.queryByPk(cusWhiteListEVO);
				if (queryCusWhiteListEVO == null || queryCusWhiteListEVO.getIntRateRatio() == null
						|| "".equals(queryCusWhiteListEVO.getIntRateRatio())) {
					taxIncomeTaxInfoVO.setCrdtAppFlowNo(lmtApplySeq);
					TaxIncomeTaxInfoVO queryTaxIncomeTaxInfoVO = taxIncomeTaxInfoService
							.queryMaxTaxIncomeTaxInfoBycrdtAppFlowNo(taxIncomeTaxInfoVO);
					if (queryTaxIncomeTaxInfoVO == null || queryTaxIncomeTaxInfoVO.getWthldngAgntNo() == null
							|| "".equals(queryTaxIncomeTaxInfoVO.getWthldngAgntNo())) {
						throw new BizException(EsbRetCodeStandard.YWLJCLYC.getValue(), "查找不到所匹配的扣缴义务人识别号");
					}
					//代扣代缴单位纳税人识别号

					String wthldngTaxpyNo = queryTaxIncomeTaxInfoVO.getWthldngAgntNo();
					taxWithholdRemitCorpVO.setWthldngTaxpyNo(wthldngTaxpyNo);
					taxWithholdRemitCorpVO.setCrdtAppFlowNo(lmtApplySeq);
					TaxWithholdRemitCorpVO queryTaxWithholdRemitCorpVO = taxWithholdRemitCorpService
							.queryTaxWithholdRemitCorpByCrdtAppFlowNoAndwthldngTaxpyNo(taxWithholdRemitCorpVO);
					if (queryTaxWithholdRemitCorpVO == null
							|| queryTaxWithholdRemitCorpVO.getWthldngCorpCityCd() == null
							|| "".equals(queryTaxWithholdRemitCorpVO.getWthldngCorpCityCd())
					||StringUtils.isEmpty(queryTaxWithholdRemitCorpVO.getWthldngCorpNm())) {
						throw new BizException(EsbRetCodeStandard.YWLJCLYC.getValue(), "查找不到所匹配的代扣代缴单位所属地市代码");
					}
					String wthldngCorpCityCd = queryTaxWithholdRemitCorpVO.getWthldngCorpCityCd();
					sTaxOrgMapVO.setTaxAreaCode(wthldngCorpCityCd);
					STaxOrgMapVO querySTaxOrgMapVO = sTaxOrgMapService.queryBySTaxOrgMapCode(sTaxOrgMapVO);
					if (querySTaxOrgMapVO == null || querySTaxOrgMapVO.getOrgCode() == null
							|| "".equals(querySTaxOrgMapVO.getOrgCode())) {
						throw new BizException(EsbRetCodeStandard.YWLJCLYC.getValue(), "查找不到所匹配的分行机构码");
					}
					String orgCode = querySTaxOrgMapVO.getOrgCode(); // 分行机构码
					orgWhiteListEVO.setOrgCode(orgCode);
					orgWhiteListEVO.setCompanyName(queryTaxWithholdRemitCorpVO.getWthldngCorpNm());
					OrgWhiteListEVO queryOrgWhiteListEVO = orgWhiteListEService.queryByPk(orgWhiteListEVO);
					if (queryOrgWhiteListEVO == null || queryOrgWhiteListEVO.getIntRateRatio() == null
							|| "".equals(queryOrgWhiteListEVO.getIntRateRatio())) {
						throw new BizException(EsbRetCodeStandard.YWLJCLYC.getValue(), "查找不到所匹配的利率浮动比");
					}
					fltIntRt = queryOrgWhiteListEVO.getIntRateRatio(); // 利率浮动比
					fltIntRt = checkDecimalInfo(fltIntRt, oneHundred_100); // 单位转换
					reqSedQueryExecRateBean.setFltIntRt(fltIntRt);
					RespSedQueryExecRateBean respSedQueryExecRateBean = sedQueryExecRateService
							.queryExecRate(reqSedQueryExecRateBean);
					intRate = respSedQueryExecRateBean.getExecRate();
				} else {
					//直接从互金查询
					fltIntRt = queryCusWhiteListEVO.getIntRateRatio(); // 利率浮动比
					fltIntRt = checkDecimalInfo(fltIntRt, oneHundred_100); // 单位转换
					reqSedQueryExecRateBean.setFltIntRt(fltIntRt);
					RespSedQueryExecRateBean respSedQueryExecRateBean = sedQueryExecRateService
							.queryExecRate(reqSedQueryExecRateBean);
					intRate = respSedQueryExecRateBean.getExecRate();
				}
			} else {
				throw new BizException(EsbRetCodeStandard.KHXXJYBTG.getValue(), "证件类型和证件号码不匹配");
			}
			return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
					JSON.toJSONString(
							buildSedQueryRateBean(EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(), "查询成功", intRate)),
					EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(),
					EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(),
					"查询成功");
		} catch (BizException e) {
			logger.error("税e贷执行利率查询接口接口处理失败!" + e.getMessage());
			return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
					JSON.toJSONString(buildSedQueryRateBean(e.getErrorCode(), e.getMessage(), intRate)), 
					EsbSysHeadEnums.RetStEnum.FAILURE.getCode(),
					e.getErrorCode(), 
					e.getMessage());
		} catch (Exception e) {
			logger.error("税e贷执行利率查询接口处理失败!" + e.getMessage());
			return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
					JSON.toJSONString(buildSedQueryRateBean(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), e.getMessage(), intRate)),
					EsbSysHeadEnums.RetStEnum.FAILURE.getCode(),
					EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(),
					e.getMessage());
		} finally {
			logger.info("税e贷执行利率查询接口结束----------查询流水号：" + lmtApplySeq + "------------全局流水号" + glblSrlNo);
			TraceUtil.clear();
		}

	}

	private void checkTrm(String loanTrm) throws BizException {

		try {
			Integer.parseInt(loanTrm);
		} catch (Exception e) {
			throw new BizException(EsbRetCodeStandard.JKYDCSJYBTG.getValue(), "请输入合法的贷款期限（整数）");
		}

	}

	private String changeTermType(String termType) {
		switch (termType) {
		case "01":
			return "D";
		case "02":
			return "M";
		case "03":
			return "Y";
		default:
			return "";
		}
	}
	private RespSedQueryRateBean buildSedQueryRateBean(String retCode, String retMsg, BigDecimal intRate) {
		RespSedQueryRateBean respSedQueryRateBean = new RespSedQueryRateBean();
		respSedQueryRateBean.setRetStCd(retCode);
		respSedQueryRateBean.setRtnMsg(retMsg);
		respSedQueryRateBean.setExecRate(Objects.isNull(intRate)?BigDecimal.ZERO:intRate.divide(new BigDecimal(100)));
		return respSedQueryRateBean;
	}

	private BigDecimal checkDecimalInfo(BigDecimal dec, int unit) {
		BigDecimal newDec = dec == null ? BigDecimal.ZERO : dec;
		if (unit != 0) {
			newDec = newDec.multiply(new BigDecimal(unit));
		}
		return newDec;  
	}

	@Autowired
	@Qualifier("lmtPrdContService")
	private LmtPrdContService lmtPrdContService;
	@Autowired
	@Qualifier("cusWhiteListEService")
	private CusWhiteListEService cusWhiteListEService;
	@Autowired
	@Qualifier("sTaxOrgMapService")
	private STaxOrgMapService sTaxOrgMapService;
	@Autowired
	@Qualifier("orgWhiteListEService")
	private OrgWhiteListEService orgWhiteListEService;
	@Autowired
	@Qualifier("taxWithholdRemitCorpService")
	private TaxWithholdRemitCorpService taxWithholdRemitCorpService;
	@Autowired
	@Qualifier("taxIncomeTaxInfoService")
	private TaxIncomeTaxInfoService taxIncomeTaxInfoService;
	@Autowired
	@Qualifier("sedQueryExecRateService")
	private SedQueryExecRateService sedQueryExecRateService;
}
